﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using WebUI.Controls;
using POSSystem.BLL;
using MyGeneration.dOOdads;

namespace WebUI
{
    public partial class StockTransfer : BasePage
    {
        public const string CATEGORY_NAME = "Other";
        public const string BRAND_NAME = "Other";
        protected void Page_Load(object sender, EventArgs e)
        {
            base.Page_Load(sender, e);
            salesLookup.OnAddIMEI = saleLookup_OnAddIMEI;
            salesLookup.OnAddProduct = saleLookup_OnAddProduct;
            if (!IsPostBack)
            {
                Utilities.LoadDropDownList(ddlBranch, Branches.GetAllBranches().DefaultView, Branches.ColumnNames.Name, Branches.ColumnNames.ID);
                NewTransfer();
            }
        }

        public void NewTransfer()
        {
            transferDetails.TransferDetails = View_TransferDetails.LoadByTransferID(0);
            transferDetails.Refresh();
            txtDescription.Text = "";
            txtTransferDate.Text = DateTime.UtcNow.AddHours(SystemVariables.SysVars.TimeZone).ToString(SystemVariables.SysVars.DateFormat);
            calTransferDate.SelectedDate = DateTime.UtcNow.AddHours(SystemVariables.SysVars.TimeZone);
            ddlBranch.SelectedValue = "";
            Sequence seq = new Sequence();
            txtNO.Text = seq.GetNewID("Transfer");
            lblUser.Text = SessionUser.s_FullName;
            btnPrint.Visible = false;
            btnTransfer.Enabled = SessionUser.BranchID == Branches.CurrentBranchID;
        }

        protected void btnRemoveTransferDetails_OnClick(object sender, EventArgs e)
        {
            transferDetails.DeleteCheckedItems();
            transferDetails.Refresh();
        }

        protected void btnTransfer_OnClick(object sender, EventArgs e)
        {
            TransactionMgr tx = TransactionMgr.ThreadTransactionMgr();

            try
            {
                View_TransferDetails viewTransDetails = transferDetails.TransferDetails;
                if(viewTransDetails.RowCount == 0)
                    throw new ApplicationException("No item to transfer.");

                if (int.Parse(ddlBranch.SelectedValue) == Branches.CurrentBranchID)
                    throw new ApplicationException("Cannot transfer from a stock location to itself.");

                tx.BeginTransaction();

                TransferHistories transfer = new TransferHistories();
                transfer.AddNew();
                transfer.TransferNO = txtNO.Text;
                transfer.FromBranchID = Branches.CurrentBranchID;
                transfer.s_ToBranchID = ddlBranch.SelectedValue;
                transfer.TransferedDate = DateTime.ParseExact(txtTransferDate.Text, calTransferDate.Format, null);
                transfer.s_Description = txtDescription.Text;
                transfer.TransferedByUserID = SessionUser.ID;

                transfer.Save();

                viewTransDetails.Rewind();
                TransferDetails transDetails = new TransferDetails();
                ProductDetailHistories productHistory = new ProductDetailHistories();
                for (int i = 0; i < viewTransDetails.RowCount; i++)
                {
                    transDetails.AddNew();

                    Products fromPd = new Products();
                    fromPd.LoadByPrimaryKey(viewTransDetails.ProductID);
                    if (fromPd.RowCount > 0 && fromPd.Deleted == false && fromPd.Quantity >= viewTransDetails.Quantity)
                    {
                        Products toPd = Products.GetProductByStockKey(transfer.ToBranchID, fromPd.StockKey);
                        if(toPd.RowCount <= 0)
                        {
                            toPd.AddNew();
                            
                            Categories cat = new Categories();
                            cat.LoadByPrimaryKey(fromPd.CategoryID);
                            if(cat.RowCount == 0)
                                throw new ApplicationException(string.Format("Category {0} is not available.", viewTransDetails.s_CategoryName));

                            Categories newCat = Categories.GetCategoryByStockKey(cat.StockKey, transfer.ToBranchID);
                            if(newCat.RowCount <= 0)
                            {
                                newCat = Categories.GetCategoryByName(CATEGORY_NAME, transfer.ToBranchID);
                                if(newCat.RowCount <= 0)
                                {
                                    newCat.AddNew();
                                    newCat.BranchID = transfer.ToBranchID;
                                    newCat.s_CategoryName = cat.s_CategoryName;
                                    newCat.s_ParentID = cat.s_ParentID;
                                    newCat.s_Level = cat.s_Level;
                                    newCat.s_VisibleToCustomer = cat.s_VisibleToCustomer;
                                    newCat.s_IsDefault = cat.s_IsDefault;
                                    newCat.s_IsDealerOnly = cat.s_IsDealerOnly;
                                    newCat.Deleted = false;
                                    newCat.LastModifiedByUser = SessionUser.ID;
                                    newCat.LastModifiedDate = DateTime.UtcNow.AddHours(SystemVariables.SysVars.TimeZone);
                                    newCat.s_StockKey = cat.s_StockKey;
                                    newCat.Save();
                                }
                            }

                            Brands brand = new Brands();
                            brand.LoadByPrimaryKey(fromPd.BrandID);
                            if(brand.RowCount == 0)
                                throw new ApplicationException(string.Format("Brand {0} is not available.", viewTransDetails.s_BrandName));

                            Brands newBrand = Brands.GetBrandByStockKey(brand.StockKey, transfer.ToBranchID);
                            if(newBrand.RowCount == 0)
                            {
                                newBrand = Brands.GetBrandByName(BRAND_NAME, transfer.ToBranchID);
                                if(newCat.RowCount == 0)
                                {
                                    newBrand.AddNew();
                                    newBrand.BranchID = transfer.ToBranchID;
                                    newBrand.BrandName = brand.BrandName;
                                    newBrand.Deleted = false;
                                    newBrand.LastModifiedByUser = SessionUser.ID;
                                    newBrand.LastModifiedDate = DateTime.UtcNow.AddHours(SystemVariables.SysVars.TimeZone);
                                    newBrand.s_StockKey = brand.s_StockKey;
                                    newBrand.Save();
                                }
                            }

                            toPd.s_BarCode = fromPd.s_BarCode;
                            toPd.BranchID = transfer.ToBranchID;
                            toPd.BrandID = newBrand.ID;
                            toPd.CategoryID = newCat.ID;
                            toPd.Cost = 0;
                            toPd.DealerPrice = 0;
                            toPd.SalePrice = 0;
                            toPd.Deleted = false;
                            toPd.s_Description = fromPd.s_Description;
                            toPd.s_GST = fromPd.s_GST;
                            toPd.s_IMEIAvailable = fromPd.s_IMEIAvailable;
                            toPd.s_IsDealerOnly = fromPd.s_IsDealerOnly;
                            toPd.s_IsHomeProduct = fromPd.s_IsHomeProduct;
                            toPd.s_IsHotProduct = fromPd.s_IsHotProduct;
                            toPd.s_IsNewArrival = fromPd.s_IsNewArrival;
                            toPd.LastModifiedByUser = SessionUser.ID;
                            toPd.LastModifiedDate = DateTime.UtcNow.AddHours(SystemVariables.SysVars.TimeZone);
                            toPd.s_Picture = fromPd.s_Picture;
                            toPd.s_ProductName = fromPd.s_ProductName;
                            toPd.Quantity = viewTransDetails.Quantity;
                            toPd.s_RegularPrice = "";
                            toPd.SoldQuantity = 0;
                            toPd.s_Thumbnail = "";
                            toPd.StockKey = fromPd.StockKey;

                            toPd.Save();
                        }
                        else
                        {
                            Products.UpdateProductQty(toPd.ID, viewTransDetails.Quantity);
                        }

                        if (viewTransDetails.s_IMEI != "")
                        {
                            ProductDetails fromDt = ProductDetails.GetByIMEI(viewTransDetails.s_IMEI, transfer.FromBranchID);
                            if (fromDt.RowCount <= 0 || fromDt.ProductStatusID == (int)ProductDetails.ProductStatus.Saled)
                                throw new ApplicationException(string.Format("Product {0} {1} not available in stock.", viewTransDetails.s_ProductName, viewTransDetails.s_IMEI));

                            ProductDetails toDt = ProductDetails.GetByIMEI(viewTransDetails.s_IMEI, transfer.ToBranchID);
                            if (toDt.RowCount > 0 && toDt.ProductStatusID == (int)ProductDetails.ProductStatus.Purchased)
                                throw new ApplicationException(string.Format("Product {0} {1} has invalid status.", viewTransDetails.s_ProductName, viewTransDetails.s_IMEI));

                            if (toDt.RowCount == 0)
                            {
                                toDt.AddNew();
                                toDt.BranchID = transfer.ToBranchID;
                                toDt.IMEI = viewTransDetails.s_IMEI;
                                toDt.ProductID = toPd.ID;
                                toDt.Deleted = false;
                                toDt.LastModifiedByUser = SessionUser.ID;
                                toDt.LastModifiedDate = DateTime.UtcNow.AddHours(SystemVariables.SysVars.TimeZone);
                                toDt.StoreDate = DateTime.UtcNow.AddHours(SystemVariables.SysVars.TimeZone);
                                toDt.s_SupplierID = fromDt.s_SupplierID;
                                toDt.s_Description = string.Format("Transfered from {0} to {1} by {2}", Branches.CurrentBranch.Name, ddlBranch.SelectedItem.Text, SessionUser.s_FullName);
                            }

                            toDt.ProductStatusID = (int)ProductDetails.ProductStatus.Purchased;
                            fromDt.ProductStatusID = (int)ProductDetails.ProductStatus.Saled;
                            fromDt.s_Description = string.Format("Transfered from {0} to {1} by {2}", Branches.CurrentBranch.Name, ddlBranch.SelectedItem.Text, SessionUser.s_FullName);
                            fromDt.LastModifiedByUser = SessionUser.ID;
                            fromDt.LastModifiedDate = DateTime.UtcNow.AddHours(SystemVariables.SysVars.TimeZone);

                            toDt.Save();
                            fromDt.Save();

                            productHistory.AddNew();
                            productHistory.AddInfo(fromDt.ID, (int)ProductDetails.ProductStatus.Saled,
                                (int)0,
                                String.Format("Transfered from {3} to {1}. User: '{2}'. Cost: {0:C}", fromPd.Cost, ddlBranch.SelectedItem.Text, SessionUser.s_FullName, Branches.CurrentBranch.Name),
                                fromDt.SupplierID, fromPd.Cost);
                            productHistory.UserID = SessionUser.ID;

                            productHistory.AddNew();
                            productHistory.AddInfo(toDt.ID, (int)ProductDetails.ProductStatus.Purchased,
                                (int)0,
                                String.Format("Transfered from {3} to {1}. User: '{2}'. Cost: {0:C}", fromPd.Cost, ddlBranch.SelectedItem.Text, SessionUser.s_FullName, Branches.CurrentBranch.Name),
                                fromDt.SupplierID, fromPd.Cost);
                            productHistory.UserID = SessionUser.ID;
                        }

                        Products.UpdateProductQty(fromPd.ID, -viewTransDetails.Quantity);

                        transDetails.s_IMEI = viewTransDetails.s_IMEI;
                        transDetails.s_ProductID = viewTransDetails.s_ProductID;
                        transDetails.s_Quantity = viewTransDetails.s_Quantity;
                        transDetails.TransferID = transfer.ID;
                    }
                    else
                        throw new ApplicationException(string.Format("Product {0} is not available or insufficient quantity.", viewTransDetails.s_ProductName));

                    viewTransDetails.MoveNext();
                }

                transDetails.Save();
                productHistory.Save();
                tx.CommitTransaction();

                hidNewID.Value = transfer.s_ID;
                ShowHintMessage(panelErr, "(*) Transfer successfully! ");
                updateErr.Update();
                btnPrint.Visible = true;
                if (chkAutoPrint.Checked)
                    PrintTransfer();
            }
            catch (Exception ex)
            {
                tx.RollbackTransaction();
                ErrorLog.WriteToFile("StockTransfer.aspx.cs", "Submit", ex.StackTrace + " " + ex.Message);
                ShowErrorMessage(panelErr, "(*) Error in transfer: " + ex.Message);
                updateErr.Update();
            }

        }

        protected void btnClear_OnClick(object sender, EventArgs e)
        {
            NewTransfer();
        }

        public void saleLookup_OnAddIMEI(object sender, ListItemEventArgs e)
        {
            try
            {
                string imei = e.Data["IMEI"].ToString();
                transferDetails.AddIMEI(imei);
            }
            catch (Exception ex)
            {
                ErrorLog.WriteToFile("Sales.aspx.cs", "saleLookup_OnAddIMEI", ex.StackTrace);
                ShowErrorMessage(panelErr, "(*) Error in add IMEI: " + ex.Message);
                updateErr.Update();
            }
        }

        public string PrintKey
        {
            get
            {
                if (ViewState["PrintKey"] == null)
                    ViewState["PrintKey"] = Guid.NewGuid().ToString();
                return ViewState["PrintKey"].ToString();
            }
        }

        public string GetPrintPage()
        {
            return this.ResolveClientUrl("~/EditPages/PrintHandler.aspx?key=") + PrintKey;
        }

        protected void PrintTransfer()
        {
            try
            {
                TransferViewerCtrl tfViewer = (TransferViewerCtrl)LoadControl(@"~/Controls/POSControls/TransferViewerCtrl.ascx");
                if (hidNewID.Value != "")
                    tfViewer.LoadTransferByID(int.Parse(hidNewID.Value));

                Session[PrintKey] = tfViewer;
                ScriptManager.RegisterClientScriptBlock(this, typeof(Page), Guid.NewGuid().ToString(), String.Format("showPrintDlg('{0}');", GetPrintPage()), true);
            }
            catch (Exception ex)
            {
                ErrorLog.WriteToFile("StockTransferCtrl.ascx.cs", "PrintInvoice", ex.StackTrace);
            }
        }

        protected void btnPrint_OnClick(object sender, EventArgs e)
        {
            PrintTransfer();
        }

        public void saleLookup_OnAddProduct(object sender, ListItemEventArgs e)
        {
            try
            {
                int productID = (int)e.Data["ProductID"];
                int quantity = (int)e.Data["Quantity"];
                transferDetails.AddNonIMEIProduct(productID, quantity);
            }
            catch (Exception ex)
            {
                ErrorLog.WriteToFile("Sales.aspx.cs", "saleLookup_OnAddProduct", ex.StackTrace);
                ShowErrorMessage(panelErr, "(*) Error in add product: " + ex.Message);
                updateErr.Update();
            }
        }
    }
}
